#include "moeutil/statechart/dsm/discrete_state_machine.h"
#include <iostream>



class RunForwardCommand
	: public discrete_event
{
public:
	RunForwardCommand(discrete_state_recorder& rec)
		: discrete_event("RunForwardCommand", rec){}
};

class WalkBackCommand
	: public discrete_event
{
public:
	WalkBackCommand(discrete_state_recorder& rec)
		: discrete_event("WalkBackCommand", rec){}
};

class PlayerRole
	: public discrete_state_recorder
{
public:
};


void handleLeave(discrete_state* dst, const discrete_event_ptr& e)
{
	std::cout<<dst->name()<<" state leave"<<std::endl;
}
void handleEnter(discrete_state* dst, const discrete_event_ptr& e)
{
	std::cout<<dst->name()<<" state enter"<<std::endl;
}
void handleUnfilter(discrete_state* dst, const discrete_event_ptr& e)
{
	std::cout<<dst->name()<<" state unfilter"<<std::endl;
}

void main()
{
	PlayerRole playerRole;

	discrete_state_machine machine("Root");
	discrete_state_machine* stopMachine = new discrete_state_machine("Stop");
	discrete_state_machine* runMachine = new discrete_state_machine("Run");

	stopMachine->sig_leave.connect(handleLeave);
	stopMachine->sig_enter.connect(handleEnter);
	runMachine->sig_leave.connect(handleLeave);
	runMachine->sig_enter.connect(handleEnter);

	machine.add_state(stopMachine);
	machine.add_state(runMachine);
	discrete_state* breathState = stopMachine->add_state(new discrete_state("Breath"));
	discrete_state* rotateState = stopMachine->add_state(new discrete_state("Rotate"));
	discrete_state* forwardState = runMachine->add_state(new discrete_state("ForwardRun"));
	discrete_state* backState = runMachine->add_state(new discrete_state("Back"));

	breathState->sig_leave.connect(handleLeave);
	breathState->sig_enter.connect(handleEnter);

	rotateState->sig_leave.connect(handleLeave);
	rotateState->sig_enter.connect(handleEnter);

	forwardState->sig_leave.connect(handleLeave);
	forwardState->sig_enter.connect(handleEnter);
	forwardState->sig_unfilter.connect(handleUnfilter);

	backState->sig_leave.connect(handleLeave);
	backState->sig_enter.connect(handleEnter);

	breathState->create_transition("RunForwardCommand", forwardState);
	breathState->create_transition("TurnAroundCommand", rotateState);
	forwardState->create_transition("WalkBackCommand", backState);

	machine.initialise(breathState, breathState);
	machine.regist_recorder(playerRole);
	machine.post_event(discrete_event_ptr(new RunForwardCommand(playerRole)));
	machine.post_event(discrete_event_ptr(new WalkBackCommand(playerRole)));
	try
	{
		machine.flush();
	}
	catch (std::exception& e)
	{
		std::cout<<e.what()<<std::endl;
	}
}